#include "transcoder_core.h"

/*x264 library lock*/
pthread_mutex_t x264_t_lock = PTHREAD_MUTEX_INITIALIZER;


extern core_t cores;

void print_fps (int exit)
{
    static int time = 0;
    time++;
    cout << to_string(time) << endl; 

    alarm(1);
    signal(SIGALRM, print_fps);
}

void output_video(trans_ctx_t *tctx, output_t *opt)
{
    int gop_count = tctx->gop_cnt;

    /* concat h264 files using ffmpeg command  */
    //ofstream mylist_file;
    //mylist_file.open(opt->tmp_dir + "/mylist.txt");

    //for (int j = 0; j < gop_count; j++)
    //    mylist_file << "file '" + to_string(j) + "." + opt->fmt + "'\n";
    //
    //mylist_file.close();

    //string command = "ffmpeg -y -f concat -i " + opt->tmp_dir + "/mylist.txt -c copy " + opt->filename;
    //system(command.c_str());
    
    /* concat h264 files using MP4Box */
    string command;
    command.reserve(gop_count * 100);
    command.append("MP4Box -force-cat");
  
    for (int j = 0; j < gop_count; j++)
    {
        command.append(" -cat ");
        command.append(opt->tmp_dir);
        command.append("/");
        command.append(to_string(j));
        command.append(".");
        command.append(opt->fmt);
    }
  
    command.append(" -new ");
    command.append(opt->filename);
    /* cout << "gop count " << gop_count << endl; */
    cout << command << endl;
    system(command.c_str());
  
    /* if (tctx->ipt.has_audio) */
    /* { */
        /* command.clear(); */
        /* command.append("MP4Box -sbr -add "); */
        /* command.append(tctx->ipt.filename); */
        /* command.append("#audio -add "); */
        /* command.append(opt->filename); */
        /* command.append("#video -delay 1="); */
        /* command.append(to_string(tctx->ipt.video_delay)); */
        /* command.append(" -new "); */
        /* command.append(opt->filename); */
        /* [>command.append(" 2>&1");<] */
        /* [>cout << command << endl;<] */
        /* system(command.c_str()); */
    /* } */

    command = "rm -rf " + opt->tmp_dir;
    system(command.c_str());
}

trans_mgr g_trans_mgr;

int main (int argc, char **argv)
{
    struct timeval start, end;
    gettimeofday(&start, NULL);

    init();

    pthread_mutex_init(&g_trans_mgr.mutex, NULL);
    
    pthread_t *threads = (pthread_t *)malloc(sizeof(pthread_t) * cores.core_cnt);
    for (int i = 0; i < cores.core_cnt; i++)
    {
        pthread_create(&threads[i], NULL, (void * (*)(void *))launch_thread, (void *)NULL);
        g_trans_mgr.avail_threads.push_back(threads[i]);
    }

    /* get the input conf file */
    string ipt_name;
    int task_num;
    int opt_num;
   
    cin >> task_num;

    vector<trans_ctx_t *> tctxs;

    /* cout << tctx->ipt.filename << " " << task_num << endl; */
    for (int i = 0; i < task_num; i++)
    {
        trans_ctx_t *tctx = new trans_ctx_t;
        cin >> tctx->ipt.filename;
        cin >> opt_num;
        /* tctx->ipt.filename = string(argv[1]); */

        for (int j = 0; j < opt_num; j++)
        {
            output_t *opt = new output_t;

            cin >> opt->filename;
            cin >> opt->fmt;
            cin >> opt->width;
            cin >> opt->height;
            cin >> opt->bitrate;

            /* cout << opt->filename << " " << endl; */
            opt->pix_fmt = AV_PIX_FMT_YUV420P;
            opt->tmp_dir = "." + opt->filename + to_string(time(nullptr));

            /* cout << opt->tmp_dir << endl; */
            mkdir(opt->tmp_dir.c_str(), ACCESSPERMS);

            tctx->opt.push_back(opt);
        }

        /* cout << tctx->ipt.filename << endl; */
        tctxs.push_back(tctx);
        /*t_ctxs.*/
    }

    alarm(1);
    signal(SIGALRM, print_fps);

    add_tctxs(tctxs);

    for (int i = 0; i < cores.core_cnt; i++)
        pthread_join(threads[i], NULL);

    
    gettimeofday(&end, NULL);

    int time = 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec-start.tv_usec);
    printf("main runs  %f\n", time/1000000.0);
    return 0;
}
